﻿using Abp.Dependency;
using Abp.Prism.Ioc;
using Castle.MicroKernel;
using Castle.MicroKernel.ComponentActivator;
using Castle.MicroKernel.Handlers;
using Castle.MicroKernel.Registration;
using CommonServiceLocator;
using Prism;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Regions.Behaviors;
using System;
using System.Windows;

namespace Abp.Prism
{
    public abstract class PrismApplication : PrismApplicationBase
    {
        protected override IContainerExtension CreateContainerExtension()
        {
            var container = new AbpContainerExtension(IocManager.Instance);
            
            return container;
        }

        protected override void RegisterRequiredTypes(IContainerRegistry containerRegistry)
        {
            base.RegisterRequiredTypes(containerRegistry);
            containerRegistry.RegisterSingleton<IRegionNavigationContentLoader, RegionNavigationContentLoader>();
            containerRegistry.RegisterSingleton<IServiceLocator, AbpServiceLocatorAdapter>();

            var serviceLocatorAdapter = this.Container.Resolve<IServiceLocator>();
            var regionBehaviorFactory = new RegionBehaviorFactory(serviceLocatorAdapter);
            containerRegistry.RegisterInstance<SelectorRegionAdapter>(new SelectorRegionAdapter(regionBehaviorFactory));
            containerRegistry.RegisterInstance<ItemsControlRegionAdapter>(new ItemsControlRegionAdapter(regionBehaviorFactory));
            containerRegistry.RegisterInstance<ContentControlRegionAdapter>(new ContentControlRegionAdapter(regionBehaviorFactory));
            var regionAdapterMappings = this.Container.Resolve<RegionAdapterMappings>();
            containerRegistry.RegisterInstance<DelayedRegionCreationBehavior>(new DelayedRegionCreationBehavior(regionAdapterMappings));
        }

        protected override void RegisterFrameworkExceptionTypes()
        {
            base.RegisterFrameworkExceptionTypes();
            ExceptionExtensions.RegisterFrameworkExceptionType(typeof(ComponentDependencyRegistrationExtensions));
            ExceptionExtensions.RegisterFrameworkExceptionType(typeof(GenericHandlerTypeMismatchException));
            ExceptionExtensions.RegisterFrameworkExceptionType(typeof(ComponentLifecycleExtension));
            ExceptionExtensions.RegisterFrameworkExceptionType(typeof(HandlerException));
            ExceptionExtensions.RegisterFrameworkExceptionType(typeof(ComponentNotFoundException));
            ExceptionExtensions.RegisterFrameworkExceptionType(typeof(CircularDependencyException));
            ExceptionExtensions.RegisterFrameworkExceptionType(typeof(ComponentRegistrationException));
            ExceptionExtensions.RegisterFrameworkExceptionType(typeof(ComponentResolutionException));
            ExceptionExtensions.RegisterFrameworkExceptionType(typeof(KernelException));
            ExceptionExtensions.RegisterFrameworkExceptionType(typeof(NoResolvableConstructorFoundException));
        }
    }
}
